001 /*
002 * Copyright 2006 Stephen J. McConnell.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.
014 *
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package net.dpml.util;
020
021 import java.io.IOException;
022
023 import org.w3c.dom.Document;
024 import org.w3c.dom.Element;
025 import org.w3c.dom.NamedNodeMap;
026 import org.w3c.dom.Node;
027
028 /**
029 * Exception related to data decoding from a DOM element.
030 */
031 public class DecodingException extends IOException
032 {
033 private final Element m_element;
034
035 /**
036 * Create a new decoding exception.
037 * @param element the element representing the source of the error
038 * @param message the exception message
039 */
040 public DecodingException( Element element, String message )
041 {
042 this( element, message, null );
043 }
044
045 /**
046 * Create a new decoding exception.
047 * @param element the element representing the source of the error
048 * @param message the exception message
049 * @param cause the causal exception
050 */
051 public DecodingException( Element element, String message, Throwable cause )
052 {
053 super( message );
054 if( null != cause )
055 {
056 super.initCause( cause );
057 }
058 m_element = element;
059 }
060
061 /**
062 * Get the element that is the subject of this exception.
063 * @return the subject element
064 */
065 public Element getElement()
066 {
067 return m_element;
068 }
069
070 /**
071 * Return a string representation of the exception.
072 * @return the string value
073 */
074 public String getMessage()
075 {
076 try
077 {
078 String message = super.getMessage();
079 StringBuffer buffer = new StringBuffer( message );
080 buffer.append( "\n" );
081 Element element = getElement();
082 String listing = list( element );
083 buffer.append( listing );
084 Document document = element.getOwnerDocument();
085 String uri = document.getDocumentURI();
086 if( null != uri )
087 {
088 buffer.append( "\nDocument: " + uri );
089 }
090 return buffer.toString();
091 }
092 catch( Throwable e )
093 {
094 return super.getMessage();
095 }
096 }
097
098 /**
099 * Static utility operation that returns a syring representation of a DOM element.
100 * @param element the element to stringify
101 * @return the string value
102 */
103 public static String list( Element element )
104 {
105 return list( element, "" );
106 }
107
108 /**
109 * Static utility operation that returns a syring representation of a DOM element.
110 * @param element the element to stringify
111 * @param pad padding offset
112 * @return the string value
113 */
114 public static String list( Element element, String pad )
115 {
116 StringBuffer buffer = new StringBuffer();
117 String tag = element.getTagName();
118 buffer.append( pad + "<" );
119 buffer.append( tag );
120 NamedNodeMap map = element.getAttributes();
121 for( int i=0; i<map.getLength(); i++ )
122 {
123 Node item = map.item( i );
124 buffer.append( " " + item.getNodeName() + "=\"" );
125 buffer.append( item.getNodeValue() );
126 buffer.append( "\"" );
127 }
128
129 Element[] children = ElementHelper.getChildren( element );
130 if( children.length > 0 )
131 {
132 buffer.append( ">" );
133 for( int i=0; i<children.length; i++ )
134 {
135 Element child = children[i];
136 String listing = list( child, pad + " " );
137 String tagName = child.getTagName();
138 buffer.append( "\n" + listing );
139 }
140 buffer.append( "\n" + pad + "</" + tag + ">" );
141 }
142 else
143 {
144 buffer.append( "/>" );
145 }
146 return buffer.toString();
147 }
148 }